package com.lanchetech.service.impl;


import com.alibaba.excel.util.CollectionUtils;
import com.baidu.fsg.uid.UidGenerator;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.vo.OrderSkuVO;
import com.lanchetech.common.enums.*;
import com.lanchetech.common.util.StringHelper;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.*;
import com.raycloud.open.sdk.api.request.KdzsPrintTradeRefundRequest;
import me.chanjar.weixin.common.service.WxService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class CommonOrderServiceImpl implements CommonOrderService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    OrderSkuMapper orderSkuMapper;

    @Autowired
    CommentStatisticsMapper commentStatisticsMapper;

    @Autowired
    FinanceService financeService;

    @Autowired
    ShopAmountMapper shopAmountMapper;

    @Autowired
    ShopMapper shopMapper;

    @Autowired
    UserCommissionMapper userCommissionMapper;

    @Autowired
    CommissionService commissionService;

    @Autowired
    WebConfigMapper webConfigMapper;

    @Autowired
    LotteryOpportunityMapper lotteryOpportunityMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    KuaidizsService kuaidizsService;

    @Resource
    UidGenerator uidGenerator;

    @Autowired
    OrderPayMapper orderPayMapper;

    @Autowired
    WxPayService wxPayService;

    @Value("${domain.url}")
    private String domainUrl;

    @Value("${wx.pay.appId}")
    private String miniAppId;

    @Value("${wx.app.appId}")
    private String appAppId;

    @Autowired
    CardFlowMapper cardFlowMapper;

    @Autowired
    UserVoucherMapper userVoucherMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    TenantFlowMapper tenantFlowMapper;

    @Autowired
    ConsumptionService consumptionService;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    RewardQueueMapper rewardQueueMapper;

    @Autowired
    BonusCountMapper bonusCountMapper;

    @Autowired
    InviteFirstBuyMapper inviteFirstBuyMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    GroupsPerformanceMapper groupsPerformanceMapper;

    @Autowired
    ShareholderPerformanceMapper shareholderPerformanceMapper;

    @Autowired
    DividendPrecipitationMapper dividendPrecipitationMapper;

    @Autowired
    IdentityMapper identityMapper;


    /**
     * 确认收货统一处理入口
     *
     * @param orders
     */
    @Override
    public void confirmOrder(Orders orders) {
        // 逐条确认收货
        ordersMapper.updateStatusAndCompleteTimeById(OrdersStatusEnum.COMMENT.getStatus(), new Date(), orders.getId());
        orderSkuMapper.updateStatusByOrderId(OrdersStatusEnum.COMMENT.getStatus(), orders.getId());

        // 给每一条添加默认5星好评，如果没有统计数据，则创建
        List<OrderSkuVO> orderSkuVOList = orderSkuMapper.findAllByOrderId(orders.getId());
        orderSkuVOList.stream().forEach(item -> commentStatisticsMapper.addOneTotalAndFiveAndDefaultFiveBySpuId(item.getSpuId()));

        // 确认收货解冻
        financeService.createFreezeAmount(orders, orders.getTotalTenantAmount().divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_DOWN), FreezeTypeEnum.CONFIRM_RECEIVE.getType());

        //佣金解冻
        List<UserCommission> userCommissionList = userCommissionMapper.findAllByOrderSkuIdInAndStatus(orderSkuVOList.stream().map(OrderSkuVO::getId).collect(Collectors.toList()), UserCommissionStatusEnum.FREEZE.getStatus());

        if (!CollectionUtils.isEmpty(userCommissionList)) {
            userCommissionList.stream().forEach(item -> {
                // 发放佣金
                commissionService.issueUserCommission(item);
            });
        }

        //添加店铺总业绩
        ShopAmount shopAmount = shopAmountMapper.findOneByShopId(orders.getTenantId());
        Shop shop = shopMapper.selectByPrimaryKey(orders.getTenantId());
        BigDecimal amount = orders.getTotalPayAmount().subtract(orders.getTotalRefundAmount());
        if (shopAmount == null) {
            shopAmountMapper.insert(ShopAmount.builder()
                    .industryFirstId(shop.getIndustryFirstId())
                    .industrySecondId(shop.getIndustrySecondId())
                    .shopId(shop.getId())
                    .amount(amount)
                    .createdAt(new Date())
                    .updatedAt(new Date())
                    .build());
        } else {
            shopAmountMapper.updateAmountAndUpdatedAtByShopId(shopAmount.getAmount().add(amount), new Date(), shop.getId());
        }

        //发放抽奖机会
        List<OrderSkuVO> orderSkuList = orderSkuMapper.findAllByOrderId(orders.getId());
        String value = webConfigMapper.findValueByName(WebConfigEnum.GIVE_OPPORTUNITY_SPU.getConfig());
        if (!StringUtils.isEmpty(value)) {
            String[] split = value.split(",");
            if (split != null && split.length > 0) {
                List<LotteryOpportunity> lotteryOpportunityList = new ArrayList<>();
                //赠送机会商品编号
                List<Long> spuIds = new ArrayList<>();
                for (String s : split) {
                    spuIds.add(Long.valueOf(s));
                }

                if (orderSkuList.size() > 0) {
                    orderSkuList.stream().forEach(item -> {
                        LotteryOpportunity lotteryOpportunity = LotteryOpportunity.builder()
                                .userId(orders.getUserId())
                                .relateId(orders.getId())
                                .type(LotteryOpportunityTypeEnum.SPU_GIVE.getType())
                                .status(LotteryOpportunityStatusEnum.NOT_USED.getStatus())
                                .remark(item.getProductName())
                                .createdAt(new Date())
                                .updatedAt(new Date())
                                .build();
                        if (spuIds.contains(item.getSpuId())) {
                            for (int i = 0; i < item.getCount(); i++) {
                                lotteryOpportunityList.add(lotteryOpportunity);
                            }
                        }
                    });
                }

                //一次机会一条记录
                if (lotteryOpportunityList.size() > 0) {
                    lotteryOpportunityMapper.batchInsert(lotteryOpportunityList);
                }
            }
        }
    }

    /**
     * 确认收货统一处理入口
     *
     * @param orders
     */
    @Override
    public void confirmOrderFreeze(Orders orders) {
        // 逐条确认收货
        ordersMapper.updateStatusAndCompleteTimeById(OrdersStatusEnum.COMMENT.getStatus(), new Date(), orders.getId());
        orderSkuMapper.updateStatusByOrderId(OrdersStatusEnum.COMMENT.getStatus(), orders.getId());

        // 给每一条添加默认5星好评，如果没有统计数据，则创建
        List<OrderSkuVO> orderSkuVOList = orderSkuMapper.findAllByOrderId(orders.getId());
        orderSkuVOList.stream().forEach(item -> commentStatisticsMapper.addOneTotalAndFiveAndDefaultFiveBySpuId(item.getSpuId()));

        // 确认收货解冻
        financeService.createFreezeAmount(orders, orders.getTotalTenantAmount().divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_DOWN), FreezeTypeEnum.CONFIRM_RECEIVE.getType());

        //添加店铺总业绩
        ShopAmount shopAmount = shopAmountMapper.findOneByShopId(orders.getTenantId());
        Shop shop = shopMapper.selectByPrimaryKey(orders.getTenantId());
        BigDecimal amount = orders.getTotalPayAmount().subtract(orders.getTotalRefundAmount());
        if (shopAmount == null) {
            shopAmountMapper.insert(ShopAmount.builder()
                    .industryFirstId(shop.getIndustryFirstId())
                    .industrySecondId(shop.getIndustrySecondId())
                    .shopId(shop.getId())
                    .amount(amount)
                    .createdAt(new Date())
                    .updatedAt(new Date())
                    .build());
        } else {
            shopAmountMapper.updateAmountAndUpdatedAtByShopId(shopAmount.getAmount().add(amount), new Date(), shop.getId());
        }
    }


    @Override
    public BaseResp closeOrder(Orders orders) {
        Orders target = ordersMapper.selectByPrimaryKey(orders.getId());
        // 如果未付款，已取消，则直接关闭;
        if (OrdersStatusEnum.UNPAY.getStatus().equals(target.getStatus()) || OrdersStatusEnum.CANCEL.getStatus().equals(target.getStatus())) {
            target.setCloseReason(orders.getCloseReason());
            target.setCloseTime(new Date());
            target.setStatus(OrdersStatusEnum.CLOSE.getStatus());
            ordersMapper.updateByPrimaryKey(target);

            //修改快递助手订单状态
            Shop shop = shopMapper.selectByPrimaryKey(orders.getTenantId());
            if (shop != null && shop.getMallUserId() != null) {
                updateKuaidizsStatus(KdzsOrderStatusEnum.ORDER_CLOSE.getStatus(), orders.getId(), shop.getMallUserId());
            }

            // orderSku也变更状态
            orderSkuMapper.updateStatusByOrderId(OrdersStatusEnum.CLOSE.getStatus(), orders.getId());
            return new BaseResp();
        }

        // 如果已付款，未发货，则先关闭，再退款
        if (OrdersStatusEnum.PAID.getStatus().equals(target.getStatus()) && LogisticsStatusEnum.UNDO.getStatus().equals(target.getLogisticsStatus())) {
            target.setCloseReason(orders.getCloseReason());
            target.setCloseTime(new Date());
            target.setStatus(OrdersStatusEnum.CLOSE.getStatus());
            target.setTotalRefundAmount(target.getTotalPayAmount());
            // 生成退款订单号
            String refundNo = Long.toString(uidGenerator.getUID());
            target.setRefundNo(refundNo);
            ordersMapper.updateByPrimaryKey(target);

            // orderSku也变更状态
            orderSkuMapper.updateStatusByOrderId(OrdersStatusEnum.CLOSE.getStatus(), target.getId());

            // 将代付订单改成已全部退款
            if (PayTypeEnum.ANOTHER_APY.getType().equals(target.getPayType())) {
                orderPayMapper.updateStatusAndUpdatedAtByTradeNo(OrderPayStatusEnum.FULL_REFUND.getStatus(), new Date(), orders.getTradeNo());
            }

            if (PayTypeEnum.WECHAT.getType().equals(target.getPayType())
                    || PayTypeEnum.ANOTHER_APY.getType().equals(target.getPayType())
                    || PayTypeEnum.APP_WECHAT.getType().equals(target.getPayType())
            ) {

                if (target.getTotalPayAmount().compareTo(BigDecimal.ZERO) > 0) {
                    // 微信支付退款
                    WxPayRefundRequest request = WxPayRefundRequest.newBuilder()
                            //订单号
                            .outTradeNo(target.getTradeNo())
                            //退款订单号
                            .outRefundNo(refundNo)
                            //原先总金额(分)
                            .totalFee(target.getTotalPayAmount().multiply(new BigDecimal(100)).intValue())
                            //退款金额(分)
                            .refundFee(target.getTotalPayAmount().multiply(new BigDecimal(100)).intValue())
                            //退款回调
                            .notifyUrl(domainUrl + "/admin-api/order/refundNotify")
                            .build();

                    WxPayRefundResult wxPayRefundResult;
                    try {
                        wxPayService.getConfig().setAppId(PayTypeEnum.APP_WECHAT.getType().equals(target.getPayType()) ? appAppId : miniAppId);
                        wxPayService.getConfig().setTradeType(PayTypeEnum.APP_WECHAT.getType().equals(target.getPayType()) ? "APP" : "JSAPI");

                        wxPayRefundResult = wxPayService.refund(request);
                        //判断退款信息是否正确
                        if ("SUCCESS".equals(wxPayRefundResult.getReturnCode()) && "SUCCESS".equals(wxPayRefundResult.getResultCode())) {
                            log.info("主动关闭订单-微信退款请求已经成功发送");
                            if (WxPayErrCodeEnum.SYSTEMERROR.getCode().equals(wxPayRefundResult.getErrCode())
                                    || WxPayErrCodeEnum.BIZERR_NEED_RETRY.getCode().equals(wxPayRefundResult.getErrCode())) {
                                log.error("主动关闭订单-微信退款请求，重新发送");
                                wxPayRefundResult = wxPayService.refund(request);
                                if ("SUCCESS".equals(wxPayRefundResult.getReturnCode()) && "SUCCESS".equals(wxPayRefundResult.getResultCode())) {
                                    log.info("主动关闭订单-微信退款请求重新发送成功");
                                } else {
                                    log.error("主动关闭订单-微信退款请求重新发送失败");
                                }
                            }
                            return new BaseResp();
                        } else {
                            log.error("主动关闭订单-微信退款请求发送失败");
                        }
                    } catch (WxPayException e) {
                        log.error("主动关闭订单-微信退款接口错误信息= {}", e);
                    }
                } else {
                    return new BaseResp();
                }

            } else if (PayTypeEnum.VIP_CARD.getType().equals(target.getPayType())) {
                // 嗨币退款
                User user = userMapper.selectByPrimaryKey(target.getUserId());
                BigDecimal cardPoint = user.getCardPoint().add(target.getTotalPayAmount());
                userMapper.updateCardPointById(cardPoint, user.getId());
                List<OrderSkuVO> orderList = orderSkuMapper.findAllByOrderId(target.getId());

                cardFlowMapper.insert(CardFlow.builder()
                        .userId(user.getId())
                        .amount(target.getTotalPayAmount())
                        .tradeType(CardTradeTypeEnum.CLOSE_ORDER.getTradeType())
                        .type(CardTradeTypeEnum.CLOSE_ORDER.getType())
                        .cardPoint(cardPoint)
                        .relateId(orders.getId())
                        .remark(StringHelper.subPayBodyString(orderList.get(0).getProductName()) + (orderList.size() > 1 ? "等" + orderList.size() + "件商品" : ""))
                        .createdAt(new Date())
                        .build());

                refundNotifyComplete(target.getRefundNo());
                return new BaseResp();
            } else if (PayTypeEnum.EXCHANGE_CARD.getType().equals(target.getPayType())) {
                // 将兑换卡变回可用状态
                List<OrderSkuVO> orderSkuVOList = orderSkuMapper.findAllByOrderId(target.getId());
                userVoucherMapper.updateStatusByUseOrderSkuId(VoucherStatusEnum.AVAILABLE.getStatus(), orderSkuVOList.get(0).getId());
                // 此时只能继续使用兑换卡，不可取消订单
                // 不用处理佣金之类的事情
            }
        }

        return new BaseResp(ResultCode.FAIL);
    }


    @Override
    public void refundNotifyComplete(String refundNo) {
        Orders orders = ordersMapper.findOneByRefundNo(refundNo);

        // 所有冻结中的佣金，要被扣回
        List<OrderSkuVO> orderSkuList = orderSkuMapper.findAllByOrderId(orders.getId());

        // 收回所有佣金
        List<UserCommission> userCommissionList = userCommissionMapper.findAllByOrderSkuIds(orderSkuList.stream().map(OrderSkuVO::getId).collect(Collectors.toList()));
        Date date = new Date();
        if (!CollectionUtils.isEmpty(userCommissionList)) {
            userCommissionList.stream().forEach(item -> {
                // 判断佣金是否是冻结状态
                if (item.getStatus().equals(UserCommissionStatusEnum.FREEZE.getStatus())) {
                    item.setStatus(UserCommissionStatusEnum.REFUND.getStatus());
                    item.setUpdatedAt(date);
                    userCommissionMapper.updateByPrimaryKeySelective(item);

                    // 将主播佣金和合伙人的主播收入退还给商家
                    if (UserCommissionTypeEnum.ANCHOR_COMMISSION.getType().equals(item.getType())
                            || UserCommissionTypeEnum.PARTNER_ANCHOR_COMMISSION.getType().equals(item.getType())) {
                        Tenant tenant = tenantMapper.selectByPrimaryKey(orders.getTenantId());
                        tenantFlowMapper.insert(TenantFlow.builder()
                                .amount(item.getCommission())
                                .tradeType(TenantTradeTypeEnum.ANCHOR_COMMISSION_REFUND.getTradeType())
                                .type(TenantTradeTypeEnum.ANCHOR_COMMISSION_REFUND.getType())
                                .point(tenant.getPoint().add(item.getCommission()))
                                .relateId(orders.getId())
                                .remark(item.getRemark())
                                .createdAt(date)
                                .tenantId(tenant.getId())
                                .build());
                        tenantMapper.updatePointById(tenant.getPoint().add(item.getCommission()), tenant.getId());
                    }
                }
            });
        }

        // 创建消费记录
        consumptionService.updateConsumptionAmount(ConsumptionRecord.builder()
                .userId(orders.getUserId())
                .amount(orders.getTotalPayAmount())
                .recordType(ConsumptionRecordTypeEnum.CLOSE_ORDER.getRecordType())
                .relateId(orders.getId())
                .build());

        OrderSkuVO orderSkuVO = orderSkuList.get(0);
        // 将商户的结算款全部收回
        if (!OrderKindEnum.COMMISSION.getKind().equals(orderSkuVO.getOrderKind()) || RushBuyStatusEnum.SUCCESS.equals(orderSkuVO.getRushBuyStatus())) {
            Tenant tenant = tenantMapper.selectByPrimaryKey(orders.getTenantId());
            tenantFlowMapper.insert(TenantFlow.builder()
                    .amount(orders.getTotalTenantAmount())
                    .tradeType(TenantTradeTypeEnum.CLOSE_ORDERS.getTradeType())
                    .type(TenantTradeTypeEnum.CLOSE_ORDERS.getType())
                    .point(tenant.getPoint().subtract(orders.getTotalTenantAmount()))
                    .relateId(orders.getId())
                    .remark(orders.getRemark())
                    .createdAt(date)
                    .tenantId(tenant.getId())
                    .build());
            tenantMapper.updatePointById(tenant.getPoint().subtract(orders.getTotalTenantAmount()), tenant.getId());
            financeService.createFreezeAmount(orders, orders.getTotalTenantAmount(), FreezeTypeEnum.CLOSE_ORDER.getType());
        }

        String memberSpu = daoService.getHipoConfigValue(HipoConfigEnum.MEMBER_SPU.getConfig());

        // 免单退款处理
        orderSkuList.stream().forEach(item -> {
            // 先判断商品是否是免单商品
            Spu spu = spuMapper.selectByPrimaryKey(item.getSpuId());
            if (SpuTypeEnum.NORMAL.getType().equals(spu.getType())) {
                //  如果此人还未领取免单奖励，则将其排队状态设置为取消
                rewardQueueMapper.updateQueueStatusByQueueStatusAndOrderSkuId(RewardQueueStatusEnum.CANCEL.getStatus(), RewardQueueStatusEnum.QUEUING.getStatus(), item.getId());
                // 无论是否领取，都将此免单商品的计数全部扣除，甚至是负数
                BonusCount bonusCount = bonusCountMapper.findOneBySpuId(item.getSpuId());
                bonusCount.setCount(bonusCount.getCount() - item.getCount());
                bonusCountMapper.updateByPrimaryKeySelective(bonusCount);
            }

            //会员商品退款扣减到期时间
            if (item.getSpuId().equals(memberSpu)) {
                Identity identity = identityMapper.findOneByUserId(orders.getUserId());
                if (identity.getMemberExpireTime() != null) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(identity.getMemberExpireTime());
                    calendar.add(Calendar.YEAR, -item.getCount() * 2);
                    identityMapper.updateMemberExpireTimeAndUpdateAtByUserId(calendar.getTime().before(date) ? date : calendar.getTime(), date, orders.getUserId());
                }
            }

            if (SpuTypeEnum.NORMAL.getType().equals(spu.getType()) || SpuTypeEnum.ORDINARY.getType().equals(spu.getType())) {
                // 将直推嗨币扣回
                CardFlow cardFlow = cardFlowMapper.findOneByTypeAndRelateId(CardTradeTypeEnum.DIRECT_RECOMMEND_REWARD.getType(), item.getId());
                if (cardFlow != null) {
                    // TODO 自行关注用户的作弊行为
                    User superior = userMapper.selectByPrimaryKey(cardFlow.getUserId());
                    cardFlowMapper.insert(CardFlow.builder()
                            .userId(superior.getId())
                            .amount(cardFlow.getAmount())
                            .tradeType(CardTradeTypeEnum.DIRECT_RECOMMEND_REFUND.getTradeType())
                            .type(CardTradeTypeEnum.DIRECT_RECOMMEND_REFUND.getType())
                            .cardPoint(superior.getCardPoint().subtract(cardFlow.getAmount()))
                            .relateId(item.getId())
                            .remark(item.getProductName())
                            .createdAt(date)
                            .performance(item.getPayAmount())
                            .build());
                    userMapper.updateCardPointById(superior.getCardPoint().subtract(cardFlow.getAmount()), superior.getId());
                }
            }

            // 如果有一人退款，则将此人的新人邀请奖励设置为未奖励
            InviteFirstBuy inviteFirstBuy = inviteFirstBuyMapper.findOneByOrderSkuId(item.getId());
            if (inviteFirstBuy != null) {

                if (InviteFirstBuyStatusEnum.REWARD.getStatus().equals(inviteFirstBuy.getStatus())) {
                    RewardQueue rewardQueue = rewardQueueMapper.selectByPrimaryKey(inviteFirstBuy.getRewardQueueId());

                    // 如果是排队中，则取消
                    if (RewardQueueStatusEnum.QUEUING.getStatus().equals(rewardQueue.getQueueStatus())) {
                        // 先取消排队
                        rewardQueue.setQueueStatus(RewardQueueStatusEnum.CANCEL.getStatus());
                        rewardQueue.setUpdateAt(date);
                        rewardQueueMapper.updateByPrimaryKeySelective(rewardQueue);

                        // 先将所有已奖励标记为未奖励
                        inviteFirstBuyMapper.updateStatusByRewardQueueIdAndStatus(InviteFirstBuyStatusEnum.NOT_REWARD.getStatus(), rewardQueue.getId(), InviteFirstBuyStatusEnum.REWARD.getStatus());
                    }
                }
                // 然后将此单的记录标记为售后取消
                inviteFirstBuy.setStatus(InviteFirstBuyStatusEnum.CANCEL.getStatus());
                inviteFirstBuyMapper.updateByPrimaryKeySelective(inviteFirstBuy);
            }
        });

        //业绩累计扣除
        commissionService.deductAddPerformance(orderSkuList);

        //修改快递助手订单状态和退款状态
        Shop shop = shopMapper.selectByPrimaryKey(orders.getTenantId());
        if (shop != null && shop.getMallUserId() != null) {
            if (shop.getMallUserId() != null) {
                updateKuaidizsStatus(KdzsOrderStatusEnum.ORDER_CLOSE.getStatus(), orders.getId(), shop.getMallUserId());

                KdzsPrintTradeRefundRequest refundRequest = new KdzsPrintTradeRefundRequest();
                refundRequest.setRefundStatus(KdzsRefundStatusEnum.REFUND_SUCCESSED.getStatus());
                refundRequest.setMallUserId(shopMapper.selectByPrimaryKey(orders.getTenantId()).getMallUserId());
                refundRequest.setTid(orders.getId().toString());
                List<Long> orderSkuIds = orderSkuList.stream().map(OrderSkuVO::getId).collect(Collectors.toList());
                List<String> orderSkuStrings = orderSkuIds.stream().map(x -> x + "").collect(Collectors.toList());
                refundRequest.setOidList(orderSkuStrings);
                kuaidizsService.refundTrade(refundRequest);
            }
        }

        //扣除本周活动补贴
        deductMarketSubsidy(orders);

        //扣除本周分红
        Map<Long, Spu> spuMap = daoService.getSpuMap(orderSkuList.stream().map(OrderSkuVO::getSpuId).collect(Collectors.toList()));
        orderSkuList.stream().forEach(item -> {
            deductDividend(orders, spuMap.get(item.getSpuId()));
        });

        //扣除本月联合创始人分红
        deductDirectorCommission(orders);

        //业绩取消
        List<GroupsPerformance> groupsPerformanceList = groupsPerformanceMapper.findAllByStatusAndOrderSkuIdIn(GroupsPerformanceStatusEnum.NOT_COUNT.getStatus(), orderSkuList.stream().map(OrderSkuVO::getId).collect(Collectors.toList()));
        if (groupsPerformanceList.size() > 0) {
            groupsPerformanceList.stream().forEach(item -> {
                item.setUpdatedAt(date);
                item.setStatus(GroupsPerformanceStatusEnum.REFUND.getStatus());
            });
            groupsPerformanceMapper.updateBatchSelective(groupsPerformanceList);
        }

        List<ShareholderPerformance> shareholderPerformanceList = shareholderPerformanceMapper.findAllByStatusAndOrderSkuIdIn(GroupsPerformanceStatusEnum.NOT_COUNT.getStatus(), orderSkuList.stream().map(OrderSkuVO::getId).collect(Collectors.toList()));
        if (shareholderPerformanceList.size() > 0) {
            shareholderPerformanceList.stream().forEach(item -> {
                item.setUpdatedAt(date);
                item.setStatus(ShareholderPerformanceStatusEnum.REFUND.getStatus());
            });
            shareholderPerformanceMapper.updateBatchSelective(shareholderPerformanceList);
        }
    }

    public void deductMarketSubsidy(Orders orders) {
        Map<String, String> config = daoService.getHipoConfigMap();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);

        DividendPrecipitation dividendPrecipitation = dividendPrecipitationMapper.findOneByTypeAndStatusAndWeekTime(DividendPrecipitationTypeEnum.MARKET_SUBSIDY.getType(), DividendPrecipitationStatusEnum.NOT_GIVE.getStatus(), calendar.getTime());

        BigDecimal amount = orders.getTotalPayAmount().negate();
        BigDecimal commission = amount.multiply(new BigDecimal(config.get(HipoConfigEnum.STATIC_DIVIDEND.getConfig())));
        if (dividendPrecipitation != null) {
            dividendPrecipitationMapper.updateDividendPrecipitation(-1, amount, commission, new Date(), dividendPrecipitation.getId());
        } else {
            dividendPrecipitationMapper.insert(DividendPrecipitation.builder()
                    .type(DividendPrecipitationTypeEnum.MARKET_SUBSIDY.getType())
                    .count(0)
                    .amount(amount)
                    .commission(commission)
                    .weekTime(calendar.getTime())
                    .status(DividendPrecipitationStatusEnum.NOT_GIVE.getStatus())
                    .updatedAt(new Date())
                    .dividendCount(0)
                    .build());
        }
    }

    //扣除本月联合创始人分红
    public void deductDirectorCommission(Orders orders) {
        Map<String, String> config = daoService.getHipoConfigMap();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);

        DividendPrecipitation dividendPrecipitation = dividendPrecipitationMapper.findOneByTypeAndStatusAndWeekTime(DividendPrecipitationTypeEnum.DIRECTOR.getType(), DividendPrecipitationStatusEnum.NOT_GIVE.getStatus(), calendar.getTime());

        BigDecimal amount = orders.getTotalPayAmount().negate();
        BigDecimal commission = amount.multiply(new BigDecimal(config.get(HipoConfigEnum.DIRECTOR_COMMISSION_RATE.getConfig())));
        if (dividendPrecipitation != null) {
            dividendPrecipitationMapper.updateDividendPrecipitation(-1, amount, commission, new Date(), dividendPrecipitation.getId());
        } else {
            dividendPrecipitationMapper.insert(DividendPrecipitation.builder()
                    .type(DividendPrecipitationTypeEnum.DIRECTOR.getType())
                    .count(-1)
                    .amount(amount)
                    .commission(commission)
                    .weekTime(calendar.getTime())
                    .status(DividendPrecipitationStatusEnum.NOT_GIVE.getStatus())
                    .updatedAt(new Date())
                    .dividendCount(0)
                    .build());
        }
    }


    //扣除本周分红
    public void deductDividend(Orders orders, Spu spu) {
        Map<String, String> config = daoService.getHipoConfigMap();
        String memberSpu = config.get(HipoConfigEnum.MEMBER_SPU.getConfig());
        String partnerSpu = config.get(HipoConfigEnum.PARTNER_SPU.getConfig());
        String shareholderSpu = config.get(HipoConfigEnum.SHAREHOLDER_SPU.getConfig());

        boolean isMemberSpu = spu.getId().equals(Long.valueOf(memberSpu));
        boolean isPartnerSpu = spu.getId().equals(Long.valueOf(partnerSpu));
        boolean isShareholderSpu = spu.getId().equals(Long.valueOf(shareholderSpu));
        boolean isOrdinarySpu = SpuTypeEnum.ORDINARY.getType().equals(spu.getType());
        boolean isCommissionSpu = SpuTypeEnum.COMMISSION.getType().equals(spu.getType());

        if ((isCommissionSpu && orders.getTotalPayAmount().compareTo(new BigDecimal(config.get(HipoConfigEnum.MEMBER_REQUIRE.getConfig()))) >= 0)
                || (isOrdinarySpu && (isMemberSpu || isPartnerSpu || isShareholderSpu))) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.HOUR_OF_DAY, 0);

            DividendPrecipitation dividendPrecipitation = dividendPrecipitationMapper.findOneByTypeAndStatusAndWeekTime(DividendPrecipitationTypeEnum.MEMBER.getType(), DividendPrecipitationStatusEnum.NOT_GIVE.getStatus(), calendar.getTime());

            BigDecimal amount = orders.getTotalPayAmount().negate();
            BigDecimal commission = amount.multiply(new BigDecimal(config.get(HipoConfigEnum.MEMBER_DIVIDENDS_1_RATE.getConfig())));
            if (dividendPrecipitation != null) {
                dividendPrecipitationMapper.updateDividendPrecipitation(-1, amount, commission, new Date(), dividendPrecipitation.getId());
            } else {
                dividendPrecipitationMapper.insert(DividendPrecipitation.builder()
                        .type(DividendPrecipitationTypeEnum.MEMBER.getType())
                        .count(0)
                        .amount(amount)
                        .commission(commission)
                        .weekTime(calendar.getTime())
                        .status(DividendPrecipitationStatusEnum.NOT_GIVE.getStatus())
                        .updatedAt(new Date())
                        .dividendCount(0)
                        .build());
            }


        }


    }

    private void updateKuaidizsStatus(String status, Long orderId, Long mallUserId) {
        KdzsPrintTradeUpdateRequest updateRequest = new KdzsPrintTradeUpdateRequest();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        updateRequest.setModified(format.format(new Date()));
        updateRequest.setTid(orderId.toString());
        updateRequest.setStatus(status);
        updateRequest.setMallUserId(mallUserId);
        kuaidizsService.updateTrade(updateRequest);
    }
}